package com.ruoyi.system.business;

import com.ruoyi.system.domain.Qstag;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.regex.Pattern;

public class FormulaUtils {

    /**
     * 判断是否有偶数个@字符
     * @param tagFormula
     * @return
     */
    public static boolean judgeEvenNumber(String tagFormula){
        if(tagFormula.contains("@")){
            char[] array = tagFormula.toCharArray();
            int number = 0;
            for(char c : array){
                if(c == '@'){
                    number++;
                }
            }
            if(number%2 == 0){
                return true;
            }
        }
        return false;
    }

    public static void recursion(String tagFormula, Map<Integer, Qstag> localTagIdMap, Map<Integer, Qstag> allQsTagOfIdMap, Map<Integer,Integer> countMap){
        List<String> tagFormulaList = FormulaUtils.getIdArrayOfFormula(tagFormula);//找到公式中的ID，如(@11@+@1178@ + @1189@ + @1199@ + @1208@-(@31@))/(@31@))*100，则找到11，1178，1189，1208，31
        if(tagFormulaList.size() > 0){
            for(String idStr : tagFormulaList){
                Integer tempId = Integer.parseInt(idStr);
                Integer number = countMap.get(tempId);
                if(number == null){
                    number = 1;//不要修改该默认值。被依赖的数据默认是1（因为这时，依赖对象被设置为计数是0），这样在排序时候，依赖对象就会排在被依赖对象后面，计算的时候就会先计算被依赖对象，然后再计算依赖对象，计算结果数据才会准确。
                }
                number = number + 1;
                countMap.put(tempId,number);

                Qstag theQsTag = allQsTagOfIdMap.get(tempId);
                if(theQsTag != null && StringUtils.hasLength(theQsTag.getItemid()) && "local".equals(theQsTag.getItemid())){
                    //否则是"local"类型自定义变量，这些变量的公式中可能会引用 其它 "local"类型自定义变量的id，所以要循环找到所有依赖非 "local"类型自定义变量 的次数，最后根据次数排序，依赖次数最大的先计算
                    Qstag tempQsTag = localTagIdMap.get(tempId);
                    if(tempQsTag != null && StringUtils.hasLength(tempQsTag.getTagformula())){
                        String tempTagFormula = tempQsTag.getTagformula();
                        if(!StringUtils.hasLength(tempTagFormula)){
                            continue;
                        }
                        FormulaUtils.recursion(tempTagFormula,localTagIdMap,allQsTagOfIdMap,countMap);
                    }
                }else{
                    //说明该tempId对应的qstag 是非"local"类型自定义变量，这种变量是实际上直接读取到PLC的数据，是固定的。不用管它用来计算的顺序问题
                    countMap.remove(tempId);
                }
            }
        }
    }

    public static List<String> getIdArrayOfFormula(String tagFormula){
        List<String> list = new ArrayList<>();
        Set<String> setList = new HashSet<>();
        if(StringUtils.hasLength(tagFormula) && tagFormula.contains("@") && FormulaUtils.judgeEvenNumber(tagFormula) ){
            String tempFormula = tagFormula;
            while (tempFormula.contains("@")){
                int firstIndex = tempFormula.indexOf("@");
                int secondIndex = tempFormula.indexOf("@",firstIndex + 1);
                int lastIndex = tempFormula.lastIndexOf("@");
                String item = tempFormula.substring(firstIndex + 1,secondIndex);
                if(StringUtils.hasLength(item)){
                    setList.add(item);
                    if(secondIndex == lastIndex){
                        //最后一项
                        tempFormula = "";
                    }else{
                        tempFormula = tempFormula.substring(secondIndex + 1);
                    }
                }else{
                    //公式不合法，需要在输入公式时候检验
                }
            }
        }
        list.addAll(setList);
        return list;
    }

    /**
     *
     * @param tagFormula  格式如： ( @8563@ + @8569@ + @8575@ ) / ( @8583@ + @8585@  + @8577@ + @8579@ + @8581@ + @8587@ *0)，或者( @5960@   + @5961@ )  / 2  等等
     * @param qsTagAllMap
     * @param drIdTagIdList  格式：drId+"." +TagId
     * @return
     */
    public static String getScript(String tagFormula, Map<Integer, Qstag> qsTagAllMap, List<String> drIdTagIdList, Map<String, String> scriptQsTagMap){
        //log.debug("输入公式：{}",tagFormula);//转化前可能是：( @5960@   + @5961@ )  / 2
        String script = "";
        if(StringUtils.hasLength(tagFormula) && tagFormula.contains("@") && judgeEvenNumber(tagFormula) ){
            String tempFormula = tagFormula;
            Map<String,String> itemQsTagMap = new HashMap<>();
            while (tempFormula.contains("@")){
                int firstIndex = tempFormula.indexOf("@");
                int secondIndex = tempFormula.indexOf("@",firstIndex + 1);
                int lastIndex = tempFormula.lastIndexOf("@");
                String item = tempFormula.substring(firstIndex + 1,secondIndex);
                if(StringUtils.hasLength(item)){
                    Qstag qstag = qsTagAllMap.get(Integer.valueOf(item.trim()));
                    if(qstag != null){
                        String tagName = qstag.getTagname();
                        Long drId = qstag.getItemdrid();
                        Long tagId = qstag.getTagid();
                        String newKeyDrIdTagId = drId + "." + tagId;
                        drIdTagIdList.add(newKeyDrIdTagId);
                        String newTagName = tagName.contains("-") ? tagName.replaceAll("-","") : tagName;
                        newTagName = newTagName.contains(":") ? newTagName.replaceAll(":","") : newTagName;
                        boolean find = Pattern.compile("(?i)[a-z]]").matcher(newTagName).find();//包含字母
                        if(!find){
                            //如果全部是数字，不允许，否则带入计算公式出错。需要增加字符
                            newTagName = "SYP" + newTagName;
                        }
                        itemQsTagMap.put(item.trim(),newTagName);
                        scriptQsTagMap.put(newKeyDrIdTagId,newTagName);
                    }
                    if(secondIndex == lastIndex){
                        //最后一项
                        tempFormula = "";
                    }else{
                        tempFormula = tempFormula.substring(secondIndex + 1);
                    }
                }else{
                    //公式不合法，需要在输入公式时候检验
                }
            }

            script = tagFormula;
            Set<String> setList = itemQsTagMap.keySet();
            for(String key : setList){
                String newTagName = itemQsTagMap.get(key);
                String replaceKey = "@" + key + "@";
                script = script.replaceAll(replaceKey,newTagName);
            }
        }
        //log.debug("转换后公式：{}",script);//转化后可能变成：( CT1112   + CT1113 )  / 2
        return script;
    }
}
